package org.apache.lucene.ocean.database;

import java.io.Serializable;
import java.rmi.Remote;

import org.apache.lucene.search.Query;

public interface OceanDatabase extends Remote {
    
  public ActionResult perform(Action action) throws Exception;
  
  /**
   * Simple generic way to execute logic on the server.  Returns an object.  Using 
   * the distributed RMI code any classes the server does not have are dynamically
   * loaded from the client in order to execute the task.  This model is used because
   * otherwise new methods must be continually created which breaks backward compatibility.  It
   * also allows dynamic class loading.  For example, the returned object may be of a class that the 
   * server previously had no knowledge of.  
   * 
   * @param task
   * @return
   * @throws Exception
   */
  public Object run(Task task) throws Exception;
    
  public static class TransactionInfo implements Serializable {
    public final long id;
    
    public TransactionInfo(long id) {
      this.id = id;
    }
  }
    
  public static class ActionResult implements Serializable {
    public final String actionId;
    public final OceanObject object;
    
    public ActionResult(String actionId) {
      this(actionId, null);
    }
    
    public ActionResult(String actionId, OceanObject object) {
      this.actionId = actionId;
      this.object = object;
    }
    
    public String toString() {
      return "actionId: "+actionId+" object: "+object;
    }
  }
  
  public static class Insert extends Action {
    public final OceanObject object;

    public Insert(String actionId, OceanObject object) {
      super(actionId);
      this.object = object;
    }
  }

  public static class Update extends Action {
    public final OceanObject object;
    
    public Update(String actionId, OceanObject object) {
      super(actionId);
      this.object = object;
    }
  }

  public static class Delete extends Action {
    public final long id;
    public final long version;

    public Delete(String actionId, long id, long version) {
      super(actionId);
      this.id = id;
      this.version = version;
    }
  }
  
  public static class DeleteQuery extends Action {
    public final Query query;

    public DeleteQuery(String actionId, Query query) {
      super(actionId);
      this.query = query;
    }
  }
  
  public static class Action implements Serializable {
    public final String actionId; // returned in Result

    public Action(String actionId) {
      this.actionId = actionId;
    }
  }
}
